subSet Problems

大佬总结链接)
核心模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if (nums.length == 0) return res;
Arrays.sort(nums);//排序很关键
helper(res, new ArrayList<>(), nums, 0);
return res;
}

//有些需要start,有些不需要
private void backtrack(List<List<Integer>> res, List<Integer> temp, int[] nums, int start){
if (满足条件){
res.add(new ArrayList<>(temp));
return;
}
for (int i = start; i < nums.length; i++){//构建循环
//1. 是否去重
//2. temp添加元素
//3. 递归调用,param变化
//4. temp去掉末尾元素
}
}

Subsets Problem

本题求子集,元素数量会变化,所以没有判断条件直接res.add()
LeetCode 78. Subsets

  • 循环start递增
    1
    2
    3
    4
    5
    6
    7
    8
    private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){
    list.add(new ArrayList<>(tempList));
    for(int i = start; i < nums.length; i++){
    tempList.add(nums[i]);
    backtrack(list, tempList, nums, i + 1);
    tempList.remove(tempList.size() - 1);
    }
    }

LeetCode 90. Subsets II

  • 循环start递增
  • 跳过重复
    1
    2
    3
    4
    5
    6
    7
    8
    9
    private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){
    list.add(new ArrayList<>(tempList));
    for(int i = start; i < nums.length; i++){
    if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
    tempList.add(nums[i]);
    backtrack(list, tempList, nums, i + 1);
    tempList.remove(tempList.size() - 1);
    }
    }

LeetCode 46. Permutations

  • 排列,需要调换顺序,所以从0开始
  • 去重
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){
    if(tempList.size() == nums.length){
    list.add(new ArrayList<>(tempList));
    } else{
    for(int i = 0; i < nums.length; i++){
    if(tempList.contains(nums[i])) continue; // element already exists, skip
    tempList.add(nums[i]);
    backtrack(list, tempList, nums);
    tempList.remove(tempList.size() - 1);
    }
    }
    }

Permutations II (contains duplicates)

  • 去重,很关键
  • 用used数组辅助
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used){
    if(tempList.size() == nums.length){
    list.add(new ArrayList<>(tempList));
    } else{
    for(int i = 0; i < nums.length; i++){
    if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue;
    used[i] = true;
    tempList.add(nums[i]);
    backtrack(list, tempList, nums, used);
    used[i] = false;
    tempList.remove(tempList.size() - 1);
    }
    }
    }

Combination Sum

1
2
3
4
5
6
7
8
9
10
11
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){
if(remain < 0) return;
else if(remain == 0) list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can reuse same elements
tempList.remove(tempList.size() - 1);
}
}
}

Combination Sum II (can’t reuse same element)

1
2
3
4
5
6
7
8
9
10
11
12
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){
if(remain < 0) return;
else if(remain == 0) list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < nums.length; i++){
if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
tempList.add(nums[i]);
backtrack(list, tempList, nums, remain - nums[i], i + 1);
tempList.remove(tempList.size() - 1);
}
}
}

Palindrome Partitioning

1
2
3
4
5
6
7
8
9
10
11
12
13
public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){
if(start == s.length())
list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < s.length(); i++){
if(isPalindrome(s, start, i)){
tempList.add(s.substring(start, i + 1));
backtrack(list, tempList, s, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
}